<template>
  <view class="code" :style="customStyle">
    <view for="code-input" class="code-bd">
      <view class="code-item" v-for="(item, index) in codeMaxLength" :key="index" :class="{ 'is-active' : isFocus && (codeArray.length === index || (codeArray.length === maxlength && index + 1 === maxlength)) }">
        <view class="code-item__dot" v-if="dot && codeArray.length > index"></view>
        <text v-else>{{ codeArray[index] }}</text>
        <view
          v-if="isFocus && (codeArray.length === index || (codeArray.length === maxlength && index + 1 === maxlength))"
          class="code-item__cursor"></view>
      </view>
    </view>
    <input :value="inputVal" @input="onInput" :cursor="inputVal.length" :focus="autoFocus" @focus="isFocus = true" @blur="isFocus = false"
      type="number" :maxlength="maxlength" class="code-input" />
  </view>
</template>

<script>

export default {
  name: 'd2-code-input',
  props: {
    customStyle: {
      type: [String, Object],
      default: "",
    },
    value: [String, Number],
    modelValue: [String, Number],
    autoFocus: {
      type: Boolean,
      default: false,
    },
    maxlength: {
      type: [String, Number],
      default: 4,
    },

    dot: {
      type: Boolean,
      default: false,
    }

  },
  data() {
    return {
      isFocus: this.autoFocus,
      inputVal: '',
    };
  },
  watch: {
    // vue2
    value: {
      immediate: true,
      handler(val) {
        this.inputVal = String(val).substring(0, this.maxlength)
      }
    },
    // vue3
    modelValue: {
      immediate: true,
      handler(val) {
        this.inputVal = String(val).substring(0, this.maxlength)
      }
    },
  },
  computed: {
    codeMaxLength() {
      return new Array(this.maxlength * 1)
    },
    codeArray() {
      return String(this.inputVal).split('')
    },
  },
  mounted() {},
  methods: {
    onInput(event) {
      let emitVal = String(event.detail.value).substring(0, this.maxlength)
      this.inputVal = emitVal
      this.$emit('change', emitVal)
      this.$emit('input', emitVal)
      this.$emit('update:modelValue', emitVal)
      if (String(emitVal).length >= Number(this.maxlength)) {
        this.$emit('finish', emitVal)
      }
    },
  },
};
</script>

<style lang="scss" scoped>
.code {
  position: relative;
  overflow: hidden;
  &-bd {
    display: flex;
    flex-wrap: wrap;
    row-gap: 16rpx;
  }

  --itemSize: 100rpx;
  // 格子
  &-item {
    flex-shrink: 0;
    position: relative;
    width: var(--itemSize);
    height: var(--itemSize);
    display: flex;
    align-items: center;
    justify-content: center;
    background: #FFFFFF;
    border-radius: 24rpx;
    font-weight: bold;
    font-size: 48rpx;
    color: #1F1F1F;
    margin-right: 16rpx;
    &:last-child {
      margin-right: 0;
    }
    // 仿制光标
    &__cursor {
      // position: absolute;
      // top: 50%;
      // left: 50%;
      // transform: translate(-50%,-50%);
      width: 1px;
      height: 40%;
      animation: 1.5s cursor-flicker infinite;
      background: #1F1F1F;
    }
    &__dot {
      width: .4em;
      height: .4em;
      border-radius: 50%;
      background: #1F1F1F;
    }
  }

  // 隐藏输入框
  &-input {
    outline: none;
    border: none;
    padding: 0;
    margin: 0;
    position: absolute;
    width: 200%;
    height: 100%;
    top: 0;
    left: -100%;
    opacity: 0;
    text-align: left;
  }
}

@keyframes cursor-flicker {
  0% {
    opacity: 0;
  }

  50% {
    opacity: 1;
  }

  100% {
    opacity: 0;
  }
}
</style>